package com.joint.web.action.com;


import com.fz.us.base.bean.BaseEnum;
import com.fz.us.base.bean.Pager;
import com.fz.us.base.util.LogUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.joint.base.entity.*;
import com.joint.base.service.*;
import com.joint.base.service.activiti.WorkflowService;
import com.joint.base.service.activiti.WorkflowTraceService;
import com.joint.base.util.DataUtil;
import com.joint.web.action.BaseAdminAction;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.HistoricVariableInstanceEntity;

import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.ParentPackage;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by hpj on 2014/9/16.
 */
@ParentPackage("com")
public class AjaxRunningAction extends BaseAdminAction {

    @Resource
    private UsersService usersService;
    @Resource
    private PostService postService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private WorkflowService workflowService;
    @Resource
    private WorkflowTraceService workflowTraceService;
    @Resource
    private ProcessConfigService processConfigService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private HistoryService historyService;
    @Resource
    private TaskService taskService;
    @Resource
    private FileManageService fileManageService;
    @Resource
    private TaskFlowService taskFlowService;
    @Resource
    private DutyService dutyService;
    //add by zhucx
    @Resource
    private TaskEntityService taskEntityService;
    //add by zhucx
    @Resource
    private ProcessBriefService processBriefService;
    //add by zhucx
    @Resource
    private StepBriefService stepBriefService;

    private Pager pager;
    private Users user;
    private Post post;
    private ProcessDefinition processDefinition;
    private List<Post> postList;
    private List<Deployment> deploymentList;
    private List<Map<String,Object>> dataRows;
    private List<Map<String,Object>> dataDeny;
    private List<Map<String,Object>> dataFinish;
    private List<TaskFlow> taskFlowList;

    private String no;
    private String name;
    private String description;
    private String keyId;
    private String bussinessId;
    private  String filePath;
    private String taskId;
    private String proId;
    private String comment;
    private String imgUrl;
    private Set<Users> usersSet;
    private String type;
    /**
     * 流程历史，流程实例
     * @return
     */
    public String list(){
        dataRows = new ArrayList<Map<String,Object>>();
        Map<String, Object> rMap;
        List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processDefinitionId(keyId).orderByProcessInstanceId().desc().list();
        for (ProcessInstance proInstance : processInstanceList) {
            processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(proInstance.getProcessDefinitionId()).singleResult();
            HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(proInstance.getId()).singleResult();
            Deployment deployment=repositoryService.createDeploymentQuery().deploymentId(processDefinition.getDeploymentId()).list().get(0);
            List<Task> taskList = taskService.createTaskQuery().processInstanceId(proInstance.getId()).active().list();

            rMap = new HashMap<String, Object>();
            rMap.put("id",proInstance.getId());
            rMap.put("name",proInstance.getName());
            rMap.put("proId",proInstance.getProcessDefinitionId());
            rMap.put("proName",deployment.getName());
            if(hpi.getStartUserId()!=null){
                rMap.put("starter", usersService.get(hpi.getStartUserId()).getName());
            }
            rMap.put("startTime", hpi.getStartTime());
            if(taskList.size()>0){
                Task task = taskList.get(0);
                List<IdentityLink> idList = taskService.getIdentityLinksForTask(task.getId());
                String name = "";
                for(IdentityLink id : idList){
                    name = name + usersService.get(id.getUserId()).getName()+",";
                }
                rMap.put("assigner",getShort(name));
            }
            rMap.put("key", processDefinition.getKey());
            dataRows.add(rMap);
        }

        return "list";
    }

    /**
     * 获取已归档流程
     * @return
     */
    public String history(){
        dataFinish = new ArrayList<Map<String, Object>>();
        Map<String, Object> rMap;

        //获取已完成的流程
        List<HistoricProcessInstance> hisProList = historyService.createHistoricProcessInstanceQuery().processDefinitionId(keyId).finished().orderByProcessInstanceStartTime().desc().list();
        for (HistoricProcessInstance hpi : hisProList) {
            rMap = new HashMap<String, Object>();
            rMap.put("id", hpi.getId());	//执行id
            rMap.put("pid",hpi.getProcessDefinitionId());
            rMap.put("starter",usersService.get(hpi.getStartUserId()).getName());
            rMap.put("pdname",repositoryService.createDeploymentQuery().deploymentId(workflowService.findProDefinitionById(keyId).getDeploymentId()).list().get(0).getName());
            rMap.put("startTime", hpi.getStartTime());
            rMap.put("endTime", hpi.getEndTime());
            rMap.put("time", new BigDecimal(hpi.getDurationInMillis() == null ? 0 : hpi.getDurationInMillis()).divide(new BigDecimal(60000), 2, BigDecimal.ROUND_HALF_EVEN)); //.divide(new BigDecimal(60000)
            dataFinish.add(rMap);
        }
        return "history";
    }

    /**
     * 审批明细
     * @return
     */
    public String comment(){
        String proInstanceId = "";
        if(StringUtils.isNotEmpty(keyId)){
            proInstanceId = keyId;
        }
        if(StringUtils.isNotEmpty(bussinessId)){
            List<HistoricProcessInstance> hpiList = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(bussinessId).list();
            if(hpiList.size()>0){
                proInstanceId = hpiList.get(0).getId();
            }
        }

        if(StringUtils.isNotEmpty(proInstanceId)){
            dataRows = workflowService.getCommentList(proInstanceId);
        }

        return "comment";
    }

    /**
     * 流程信息
     * @return
     */
    public String workflow(){
        TaskEntity taskEntity = taskEntityService.getInfoByKeyId(bussinessId);
        taskFlowList = Lists.newArrayList();
        usersSet = Sets.newHashSet();
        if(taskEntity == null){
            if(StringUtils.equals("next", type)){
                return "next";
            }
            return "workflow";
        }
        taskFlowList = taskFlowService.getInfoByTaskEntity(taskEntity);
        ProcessBrief processBrief = processBriefService.getInfoByTableKey(taskEntity.getEntityName());
        StepBrief stepBrief = stepBriefService.getInfoByStepNo(processBrief, taskEntity.getStepNo());
        if(stepBrief != null){
            usersSet =  taskEntity.getEditors();
        }
        if(StringUtils.equals("next", type)){
            return "next";
        }
        return "workflow";
    }

    /**
     * 审批明细
     * @return
     */
    public String workflow1(){
        String proInstanceId = "";
        String userId = "";
        Date startTime = null;
        Map<String, Object> rMap = new HashMap<String, Object>();
        if(StringUtils.isNotEmpty(keyId)){
            proInstanceId = keyId;
        }
        if(StringUtils.isNotEmpty(bussinessId)){
            List<HistoricProcessInstance> hpiList = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(bussinessId).list();
            if(hpiList.size()>0){
                proInstanceId = hpiList.get(0).getId();
                userId = hpiList.get(0).getStartUserId();
                startTime = hpiList.get(0).getStartTime();
            }
        }
        usersSet = Sets.newHashSet();
        dataRows = Lists.newArrayList();
        if(StringUtils.isNotEmpty(proInstanceId)){
            if(StringUtils.isNotEmpty(userId)){
                List<HistoricVariableInstance> histance = historyService.createHistoricVariableInstanceQuery().processInstanceId(proInstanceId).variableName("initDuty").list();
                // todo 获取本地历史变量调用字service
                String dutyId = "";
                if(histance.size()>0){
                    HistoricVariableInstanceEntity hisVarEntity = (HistoricVariableInstanceEntity) histance.get(0);
                    dutyId = hisVarEntity.getTextValue();
                }
                Users users = usersService.get(userId);
                rMap.put("id","");
                rMap.put("assignee", users.getName());
                rMap.put("startTime", DataUtil.DateTimeToString(startTime));
                if(com.joint.base.util.StringUtils.isNotEmpty(dutyId)){
                    rMap.put("curDuty",dutyService.get(dutyId));
                }
            }
            dataRows.add(rMap);
            dataRows.addAll(workflowService.getCommentList(proInstanceId));
            List<Task> taskList = taskService.createTaskQuery().processInstanceId(proInstanceId).active().orderByTaskCreateTime().desc().list();
            for(Task task:taskList){
                //新建和退回状态从activity流程引擎选，其他从自定义任务流程数据中查
               if (StringUtils.equals(task.getTaskDefinitionKey(),"usertask1") ){
                   if(StringUtils.isNotEmpty(task.getAssignee())){
                       Users users = usersService.get(task.getAssignee());
                       usersSet.add(users);
                   }
               }else{
                   List<Users> usersList =taskFlowService.findUsersByTaskFlow(task.getId());
                   usersSet.addAll(usersList);
               }
            }
        }
        if(StringUtils.equals("next", type)){
            return "next";
        }
        return "workflow";
    }
    /**
     * 查看流程图
     * @return
     * @throws IOException
     */
    public String export() throws IOException {
        ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
        ProcessInstance pi = (ProcessInstance) processInstanceQuery.processInstanceId(keyId).singleResult();
        String processDefinitionId = pi.getProcessDefinitionId();
        List<FileManage> fileManageList = fileManageService.getFileByKeyId(processDefinitionId);
        if(fileManageList.size() > 0){
            FileManage fileManage = fileManageList.get(0);
            filePath = fileManage.getUrl();
        }
        processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        return "export";
    }


    /**
     * 附件上传的dialog，失败返回访问被拒绝
     * @return
     */
    public String addAttachDlg(){
        if(isAdd()){
            return "addAttachDlg";
        }
        return "denied";
    }
    /**
     * 添加评论
     * @return
     */
    public String addComment(){
        if(isAdd()){
            Task task=workflowService.getCurrentTask(keyId,usersService.getLoginInfo());
            taskService.addComment(task.getId(),task.getProcessInstanceId(),comment);
            return ajaxHtmlCallback("200", "评论成功！","操作状态");
        }
        return ajaxHtmlCallback("400", "只有当前操作人员才可以评论！", "操作状态");
    }

    /**
     * 判断是否具有添加评论或者添加附件的权限
     * @return
     */
    private boolean isAdd(){
        if(StringUtils.isNotEmpty(keyId)){
            Users users = usersService.getLoginInfo();
            List<Task> taskList = taskService.createTaskQuery().taskCandidateOrAssigned(users.getId()).processInstanceBusinessKey(keyId).list();
            return  taskList.size()==0?false:true;
        }
        return false;
    }
    /**
     * 获取流程实例所有节点信息
     * @return
     * @throws Exception
     */
    public String activitis() throws Exception{
        List<Map<String, Object>> activityInfos;
        activityInfos = workflowService.traceHistoryProcess(keyId);

        List<JSONObject> dataRows = new ArrayList<JSONObject>();
        for(Map<String,Object> stepMap:activityInfos){
            dataRows.add(JSONObject.fromObject(stepMap));
        }
        return ajaxJson(JSONArray.fromObject(dataRows).toString());
    }

    public String allActivity() throws Exception {
        List<Map<String, Object>> activityInfos = workflowService.allActivities(keyId);
        List<JSONObject> dataRows = new ArrayList<JSONObject>();
        for(Map<String,Object> stepMap:activityInfos){
            dataRows.add(JSONObject.fromObject(stepMap));
        }
        return ajaxJson(JSONArray.fromObject(dataRows).toString());
    }

    public String openDoc() throws IOException, InterruptedException {


        return null;
    }

    public Pager getPager() {
        return pager;
    }

    public void setPager(Pager pager) {
        this.pager = pager;
    }

    public List<Post> getPostList() {
        return postList;
    }

    public void setPostList(List<Post> postList) {
        this.postList = postList;
    }

    public Users getUser() {
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }

    public String getKeyId() {
        return keyId;
    }

    public void setKeyId(String keyId) {
        this.keyId = keyId;
    }

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


    public List<Deployment> getDeploymentList() {
        return deploymentList;
    }

    public void setDeploymentList(List<Deployment> deploymentList) {
        this.deploymentList = deploymentList;
    }


    public List<Map<String, Object>> getDataRows() {
        return dataRows;
    }

    public void setDataRows(List<Map<String, Object>> dataRows) {
        this.dataRows = dataRows;
    }

    public ProcessDefinition getProcessDefinition() {
        return processDefinition;
    }

    public void setProcessDefinition(ProcessDefinition processDefinition) {
        this.processDefinition = processDefinition;
    }

    public List<Map<String, Object>> getDataDeny() {
        return dataDeny;
    }

    public void setDataDeny(List<Map<String, Object>> dataDeny) {
        this.dataDeny = dataDeny;
    }

    public List<Map<String, Object>> getDataFinish() {
        return dataFinish;
    }

    public void setDataFinish(List<Map<String, Object>> dataFinish) {
        this.dataFinish = dataFinish;
    }

    public String getBussinessId() {
        return bussinessId;
    }

    public void setBussinessId(String bussinessId) {
        this.bussinessId = bussinessId;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getProId() {
        return proId;
    }

    public void setProId(String proId) {
        this.proId = proId;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public Set<Users> getUsersSet() {
        return usersSet;
    }

    public void setUsersSet(Set<Users> usersSet) {
        this.usersSet = usersSet;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public List<TaskFlow> getTaskFlowList() {
        return taskFlowList;
    }

    public void setTaskFlowList(List<TaskFlow> taskFlowList) {
        this.taskFlowList = taskFlowList;
    }
}
